import axios, { AxiosInstance } from 'axios';

// 定义 API 配置接口
interface DifyConfig {
  baseURL: string;
  apiKey: string;
}

type StreamEvent = 
  | { event: 'workflow_started', data: WorkflowStartedEventData }
  | { event: 'node_started', data: NodeEventData }
  | { event: 'node_finished', data: NodeFinishedEventData }
  | { event: 'workflow_finished', data: WorkflowFinishedEventData }
  | { event: 'message', data: MessageEventData }
  | { event: 'message_end', data: MessageEndEventData }
  | { event: 'tts_message', data: TTSMessageEventData }
  | { event: 'tts_message_end', data: TTSMessageEndEventData }
  | { event: 'error', data: ErrorEventData }
  | { event: 'message_file', data: MessageFileEventData } // 新增
  | { event: 'message_replace', data: MessageReplaceEventData }; 
// Add missing interfaces 
interface NodeEventData {
  task_id: string;
  workflow_run_id: string;
  data: {
    id: string;
    node_id: string;
    node_type: string;
    title: string;
    index: number;
    predecessor_node_id: string;
    inputs: Record<string, any>;
    created_at: number;
  };
}

// 新增事件接口
interface MessageFileEventData {
  id: string;
  type: string;
  belongs_to: string;
  url: string;
  conversation_id: string;
}

interface MessageReplaceEventData {
  task_id: string;
  message_id: string;
  conversation_id: string;
  answer: string;
  created_at: number;
}
 
interface NodeFinishedEventData extends NodeEventData {
  data: NodeEventData['data'] & {
    outputs: Record<string, any>;
    status: string;
    elapsed_time: number;
    execution_metadata: {
      total_tokens: number;
      total_price: number;
      currency: string;
    };
  };
}
 
interface WorkflowFinishedEventData {
  task_id: string;
  workflow_run_id: string;
  data: {
    id: string;
    workflow_id: string;
    outputs: Record<string, any>;
    status: string;
    elapsed_time: number;
    total_tokens: number;
    total_steps: string;
    created_at: number;
    finished_at: number;
  };
}
 
interface TTSMessageEventData {
  conversation_id: string;
  message_id: string;
  created_at: number;
  task_id: string;
  audio: string;
}
 
interface TTSMessageEndEventData {
  conversation_id: string;
  message_id: string;
  created_at: number;
  task_id: string;
  audio: string;
}

// 定义流式事件类型

interface MessageEventData {
  task_id: string;
  message_id: string;
  conversation_id: string;
  answer: string;
  created_at: number;
}

interface MessageEndEventData {
  task_id: string;
  conversation_id: string;
  message_id: string;
  metadata: {
    usage: UsageData;
    retriever_resources: RetrieverResource[];
  };
}

interface UsageData {
  prompt_tokens: number;
  completion_tokens: number;
  total_tokens: number;
  total_price: number;
  currency: string;
}

interface RetrieverResource {
  position: number;
  dataset_id: string;
  dataset_name: string;
  document_id: string;
  document_name: string;
  segment_id: string;
  score: number;
  content: string;
}

interface ErrorEventData {
  task_id?: string;
  message_id?: string;
  status?: number;
  code: string;
  message: string;
}

interface WorkflowStartedEventData {
  task_id: string;
  workflow_run_id: string;
  data: any;
}

// 定义消息发送参数
export interface SendMessageParams {
  inputs: Record<string, any>;
  query: string;
  response_mode: 'streaming' | 'blocking';
  conversation_id?: string;
  user: string;
  files?: Array<{
    type: string;
    transfer_method: 'remote_url' | 'local_file';
    url?: string;
    upload_file_id?: string;
  }>;
  auto_generate_name?: boolean;
}

// Dify API 服务类
class DifyApiService {
  private api: AxiosInstance;
  
  constructor(config: DifyConfig) {
    this.api = axios.create({
      baseURL: config.baseURL,
      headers: {
        'Authorization': `Bearer ${config.apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  /**
   * 发送对话消息（流式）
   */
  async sendStreamMessage(
  params: SendMessageParams,
  onEvent: (event: StreamEvent) => void 
): Promise<void> {
  const requestParams = { ...params, response_mode: 'streaming' };
  const response = await fetch(`${this.api.defaults.baseURL}/chat-messages`,  {
    method: 'POST',
    headers: {
      'Authorization': this.api.defaults.headers['Authorization']  as string,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestParams)
  });
 
  if (!response.ok)  {
     const errorData = await response.json().catch(() => ({}));
     throw new Error(
        `Request failed with status ${response.status}: ${errorData.message || response.statusText}`
     );
  }
 
  if (!response.body)  {
     throw new Error('No response body available');
  }
 
  const reader = response.body.getReader(); 
  const decoder = new TextDecoder('utf-8');

  let buffer = '';
    // 存储各消息的累积内容
  const messageAccumulators: Record<string, string> = {};
 
  // 递归处理流数据
    const processChunk = async (): Promise<void> => {
      try {
        const { done, value } = await reader.read();
        
        if (done) {
          // 处理剩余缓冲区内容
          if (buffer.trim()) {
            try {
              const lines = buffer.split('\n');
              for (const line of lines) {
                if (line.startsWith('data:')) {
                  const dataStr = line.substring(5).trim();
                  if (dataStr) {
                    this.processEventData(dataStr, messageAccumulators, onEvent);
                  }
                }
              }
            } catch (error) {
              console.error('Error parsing final buffer:', error);
              onEvent({
                event: 'error',
                data: {
                  code: 'FINAL_PARSE_ERROR',
                  message: `Failed to parse final buffer: ${(error as Error).message}`
                }
              });
            }
          }
          return;
        }
        
        // 解码并添加到缓冲区
        buffer += decoder.decode(value, { stream: true });
        
        // 处理完整的事件（以两个换行符分隔）
        let eventEndIndex;
        while ((eventEndIndex = buffer.indexOf('\n\n')) !== -1) {
          const eventData = buffer.substring(0, eventEndIndex).trim();
          buffer = buffer.substring(eventEndIndex + 2);
          
          // 跳过空事件
          if (!eventData) continue;
          
          // 处理事件行
          const lines = eventData.split('\n');
          for (const line of lines) {
            if (line.startsWith('data:')) {
              const dataStr = line.substring(5).trim();
              if (dataStr) {
                this.processEventData(dataStr, messageAccumulators, onEvent);
              }
            }
          }
        }
        
        // 递归处理下一个块
        await processChunk();
      } catch (error) {
        console.error('Error processing chunk:', error);
        onEvent({
          event: 'error',
          data: {
            code: 'STREAM_PROCESSING_ERROR',
            message: `Stream processing failed: ${(error as Error).message}`
          }
        });
      }
    };
    
    // 开始处理流
    await processChunk();
}

private processEventData(
  dataStr: string,
  messageAccumulators: Record<string, string>,
  onEvent: (event: StreamEvent) => void
) {
  try {
    const data = JSON.parse(dataStr);
    const eventType = data.event || 'unknown';
    
    // 特殊事件处理
    switch (eventType) {
      case 'ping':
        // 保持连接的心跳事件，不需要处理
        return;
        
      case 'message':
        // 消息分片处理
        if (data.message_id) {
          if (!messageAccumulators[data.message_id]) {
            messageAccumulators[data.message_id] = '';
          }
          messageAccumulators[data.message_id] += data.answer;
          data.answer = messageAccumulators[data.message_id];
          console.log(data.answer)
        }
        break;
        
      case 'message_replace':
        // 消息替换处理
        if (data.message_id && messageAccumulators[data.message_id]) {
          messageAccumulators[data.message_id] = data.answer;
        }
        break;
        
      case 'tts_message':
        // 处理TTS音频
        if (data.audio) {
          this.handleTTSAudio(data.audio, data.message_id, onEvent);
        }
        break;
    }
    
    // 触发事件回调
    onEvent({
      event: eventType as StreamEvent['event'],
      data
    });
    
  } catch (parseError) {
    console.error('Error parsing event data:', parseError, 'Data:', dataStr);
    onEvent({
      event: 'error',
      data: {
        code: 'PARSE_ERROR',
        message: `Failed to parse event data: ${(parseError as Error).message}`
      }
    });
  }
}

/**
 * 处理TTS音频数据
 */
private handleTTSAudio(
  base64Audio: string,
  messageId: string,
  onEvent: (event: StreamEvent) => void
) {
  try {
    // 解码base64音频数据
    const binaryString = atob(base64Audio);
    const bytes = new Uint8Array(binaryString.length);
    for (let i = 0; i < binaryString.length; i++) {
      bytes[i] = binaryString.charCodeAt(i);
    }
    
    // 创建音频Blob
    const audioBlob = new Blob([bytes], { type: 'audio/mp3' });
    const audioUrl = URL.createObjectURL(audioBlob);
    
    // 触发自定义音频就绪事件
    onEvent({
      event: 'tts_audio_ready',
      data: {
        url: audioUrl,
        message_id: messageId
      }
    } as any);
    
  } catch (audioError) {
    console.error('TTS audio decoding failed:', audioError);
    onEvent({
      event: 'error',
      data: {
        code: 'TTS_ERROR',
        message: `TTS audio decoding failed: ${(audioError as Error).message}`
      }
    });
  }
}

  /**
   * 停止响应
   */
  async stopResponse(taskId: string, user: string): Promise<void> {
    await this.api.post(`/chat-messages/${taskId}/stop`, { user });
  }

  /**
   * 上传文件
   */
  async uploadFile(file: File, user: string): Promise<any> {
    const formData = new FormData();
    formData.append('file', file);
    formData.append('user', user);

    return this.api.post('/files/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
  }

  /**
   * 获取会话历史
   */
  /**
   * 从API获取对话消息
   *
   * @param conversationId 对话ID
   * @param user 用户ID
   * @returns 返回API调用结果，包含消息信息
   */
  async getMessages(conversationId: string, user: string): Promise<any> {
    return this.api.get('/messages', {
      params: { conversation_id: conversationId, user }
    });
  }

  /**
   * 获取会话列表
   */
  async getConversations(user: string): Promise<any> {
    return this.api.get('/conversations', { params: { user } });
  }

  /**
   * 删除会话
   */
  async deleteConversation(conversationId: string, user: string): Promise<void> {
    await this.api.delete(`/conversations/${conversationId}`, {
      data: { user }
    });
  }

  // 消息反馈
  async sendFeedback(messageId: string, rating: 'like' | 'dislike' | 'null', user: string, content?: string) {
    return this.api.post(`/messages/${messageId}/feedbacks`, {
      rating,
      user,
      content
    });
  }

   // 获取建议问题
  async getSuggestedQuestions(messageId: string, user: string) {
    return this.api.get(`/messages/${messageId}/suggested`, {
      params: { user }
    });
  }

  // 会话重命名
  async renameConversation(conversationId: string, name: string, user: string, autoGenerate = false) {
    return this.api.post(`/conversations/${conversationId}/name`, {
      name,
      auto_generate: autoGenerate,
      user
    });
  }

   // 获取对话变量
  async getConversationVariables(conversationId: string, user: string) {
    return this.api.get(`/conversations/${conversationId}/variables`, {
      params: { user }
    });
  }

   // 语音转文字
  async audioToText(file: File) {
    const formData = new FormData();
    formData.append('file', file);
    return this.api.post('/audio-to-text', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
  }


  // 文字转语音
  async textToAudio(text: string, user: string, messageId?: string) {
    return this.api.post('/text-to-audio', {
      text,
      user,
      message_id: messageId
    });
  }

  
  // 获取应用参数
  async getAppParameters() {
    return this.api.get('/parameters');
  }
  // 其他API方法根据文档实现...
}

// 导出单例实例
export const difyApi = new DifyApiService({
  baseURL: '/dify/v1',
   apiKey: `${process.env.VUE_APP_LOCAL_API_KEY}` // 实际应用中应从环境变量获取
  //apiKey:'app-GIyo8mqLP0uTIylh6gBIpJIb',
});